#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <cassert>
#include <cstring>
#include <fcntl.h>

#include "Log.hpp"

using namespace std;

#define PATH_NAME "/home/hbr/linux/5.procIPC/4.sharedmemory"
#define PROJ_ID 0x66
#define SHM_SIZE 4096
#define FIFO_NAME "./fifo"

#define READ O_RDONLY
#define WRITE O_WRONLY

class Init
{
public:
    Init()
    {
        umask(0);
        // 检查FIFO是否已经存在
        if (access(FIFO_NAME, F_OK) == -1)
        {
            // 如果FIFO不存在，则创建
            int n = mkfifo(FIFO_NAME, 0666);
            if (n != 0)
            {
                perror("Failed to create FIFO");
                exit(1);
            }
            Log("create fifo success", Notice) << "\n";
        }
        else
        {
            // 如果FIFO已经存在，则记录日志
            Log("FIFO already exists", Notice) << "\n";
        }
    }
    ~Init()
    {
        unlink(FIFO_NAME);
        Log("remove fifo success", Notice) << "\n";
    }
};

int OpenFIFO(std::string pathname, int flags)
{
    int fd = open(pathname.c_str(), flags);
    if (fd < 0)
    {
        perror("Failed to open FIFO");
        exit(EXIT_FAILURE);
    }
    return fd;
}

void Wait(int fd)
{
    Log("waiting for signal", Notice) << "\n";
    uint32_t temp = 0;
    ssize_t s = read(fd, &temp, sizeof(uint32_t));
    if (s != sizeof(uint32_t))
    {
        perror("Failed to read from FIFO");
        exit(EXIT_FAILURE);
    }
}

void Signal(int fd)
{
    uint32_t temp = 1;
    ssize_t s = write(fd, &temp, sizeof(uint32_t));
    if (s != sizeof(uint32_t))
    {
        perror("Failed to write to FIFO");
        exit(EXIT_FAILURE);
    }
    Log("Process waking up", Notice) << "\n";
}
void CloseFIFO(int fd)
{
    if (close(fd) < 0)
    {
        perror("Failed to close FIFO");
        exit(EXIT_FAILURE);
    }
}